/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package vn.support.system;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import vn.support.core.dto.DataObject;
import vn.support.ui.ChatView;
import vn.support.ui.View;

/**
 *
 * @author nttuyen
 */
public class SystemProperties {

    public static final String SYSTEM_BUNDLE = "system";
    public static final String SYSTEM_DATA_FILE = "data.osp";
    
    public static final int SYSTEM_SOCKET_PORT = 9911;
    public static final int SYSTEM_START_OK = 200;
    public static final int SYSTEM_START_ALREADY = 1;
    public static final int SYSTEM_START_FAILURE = -1;

    private final DataObject data;
    
    public static final String MAIN_FRAME = "system.main.frame";
    public static final String TRAY_ICON = "system.trayicon";
    public static final String SESSION = "system.session";
    public static final String CURRENT_STATUS = "system.status";
    public static final String STAFFS = "system.staffs";
    public static final String VISITORS = "system.visitors";
    public static final String VIEWS = "system.views";
    public static final String BUNDLES = "system.bundles";
    public static final String SOCKET_SERVER = "system.socket.server";
    public static final String URL = "system.server.url";

    private Map<String, String> smiles = new HashMap<String, String>();
    
    private static SystemProperties system = new SystemProperties();
    
    public static DataObject getData() {
        return system.data;
    }

    public static <T> void set(String key, T value) {
        synchronized(system.data) {
            system.data.set(key, value);
        }
    }
    public static <T> T get(String key) {
        try {
            synchronized(system.data) {
                return (T)system.data.get(key);
            }
        }catch (Throwable e){
            return null;
        }
    }
    
    public static void addView(View view) {
        Collection<View> views = get(VIEWS);
        views.add(view);
    }
    public static void removeView(View view) {
        Collection<View> views = get(VIEWS);
        views.remove(view);
    }
    
    public static synchronized Locale getLocale() {
        return Locale.getDefault();
    }
    public static synchronized void setLocale(Locale locale) {
        Locale.setDefault(locale);
        Collection<ResourceBundle> bundles = get(BUNDLES);
        bundles.clear();
        bundles.add(ResourceBundle.getBundle(SYSTEM_BUNDLE));
        bundles.add(ResourceBundle.getBundle(View.UI_BUNDLE));
        
        //Collection
        Collection<View> views = get(VIEWS);
        for(View view : views) {
            view.refresh();
        }
    }
    public static Locale[] getSupportedLocale() {
        return new Locale[] {
            Locale.ROOT,
            Locale.ENGLISH
        };
    }
    
    public static String getValue(String name) {
        Collection<ResourceBundle> bundles = get(BUNDLES);
        for(ResourceBundle bundle : bundles) {
            if(bundle.containsKey(name)) {
                return bundle.getString(name);
            }
        }
        return name;
    }
    
    public static Icon getIcon(String name) {
        String path = name;
        Collection<ResourceBundle> bundles = get(BUNDLES);
        for(ResourceBundle bundle : bundles) {
            if(bundle.containsKey(name)) {
                path = bundle.getString(name);
            }
        }
        try {
            Icon icon = new ImageIcon(system.getClass().getResource(path));
            return icon;
        } catch (Throwable e) {}

        return null;
    }
    
    public static String emotionMessage(String message) {
        for(String smile : system.smiles.keySet()) {
            message = message.replace(smile, getSmile(smile));
        }
        return message;
    }
    
    public static synchronized void save() {
        //TODO: Save file info
        Properties properties = new Properties();
        properties.put(URL, get(URL));
        try {
            FileOutputStream out = new FileOutputStream(SYSTEM_DATA_FILE);
            properties.store(out, "System data");
        } catch(Exception e) {}
    }
    
    public static synchronized void shutdown() {
        //Shutdown view
        Collection<View> views = get(VIEWS);
        for(View view : views) {
            if(view instanceof ChatView) {
                ((ChatView)view).endChat();
            }
        }
        //Close socket
        try {
            ServerSocket socket = get(SOCKET_SERVER);
            socket.close();
        } catch (IOException ex) {
            Logger.getLogger(SystemProperties.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    protected SystemProperties() {
        this.data = new DataObject(SystemProperties.class.getName());
        
        this.data.set(CURRENT_STATUS, new Integer(1));
        this.data.set(VIEWS, new LinkedList<View>());
        this.data.set(BUNDLES, new LinkedList<ResourceBundle>());
        
        //Init bundle
        Collection<ResourceBundle> bundles = this.data.get(BUNDLES);
        bundles.add(ResourceBundle.getBundle(SYSTEM_BUNDLE));
        bundles.add(ResourceBundle.getBundle(View.UI_BUNDLE));
        
        this.data.set(URL, "http://nttuyen.com/test/support/winapp/index.php");
        
        this.setupSmile();
    }
    
    public static synchronized int init() {
        int ret = SYSTEM_START_FAILURE;
        try {
            final ServerSocket socket = new ServerSocket(SYSTEM_SOCKET_PORT);
            set(SOCKET_SERVER, socket);
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        while(true) {
                            Socket s = socket.accept();
                            JFrame frame = get(MAIN_FRAME);
                            if(frame != null) {
                                frame.setVisible(true);
                            }
                            s.close();
                        }
                    } catch (IOException ex) {
                        Logger.getLogger(SystemProperties.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }).start();
            ret = SYSTEM_START_OK;
        } catch (IOException ex) {
            Logger.getLogger(SystemProperties.class.getName()).log(Level.SEVERE, null, ex);
            try {
                Socket s = new Socket("127.0.0.1", SYSTEM_SOCKET_PORT);
                s.close();
                return SYSTEM_START_ALREADY;
            } catch (UnknownHostException ex1) {
                Logger.getLogger(SystemProperties.class.getName()).log(Level.SEVERE, null, ex1);
            } catch (IOException ex1) {
                Logger.getLogger(SystemProperties.class.getName()).log(Level.SEVERE, null, ex1);
            }
        }
        
        if(ret == SYSTEM_START_OK) {
            //Load data
            Properties properties = new Properties();
            try {
                properties.load(new FileInputStream(SYSTEM_DATA_FILE));
            } catch (Exception e) {}
            Set<?> keySet = properties.keySet();
            for(Object key : keySet) {
                set(key.toString(), properties.get(key));
            }
        }
        
        return ret;
    }
    
//    public static void setSession(SessionData session) {
//        set(SESSION, session);
//    }
//    public static SessionData getSession() {
//        return get(SESSION);
//    }

//    public static void setMainFrame(JFrame frame) {
//        set(MAIN_FRAME, frame);
//    }
//    public static JFrame getMainFrame() {
//        return get(MAIN_FRAME);
//    }
    
//    public static void setTrayIcon(TrayIcon trayIcon) {
//        set(TRAY_ICON, trayIcon);
//    }
//    public static TrayIcon getTrayIcon() {
//        return get(TRAY_ICON);
//    }

//    public static void setStatus(int status) {
//        set(CURRENT_STATUS, new Integer(status));
//    }
//    public static int getStatus() {
//        Integer status = get(CURRENT_STATUS);
//        return status.intValue();
//    }
    

    protected static String getSmile(String smile) {
        if(system.smiles.containsKey(smile)) {
            String url = system.getClass().getResource(system.smiles.get(smile)).toString();
            return String.format(getValue("support.chat.message.emotion.img.tag"), url);
        }
        return smile;
    }

    protected final void setupSmile() {
        this.smiles.put(":)", "/emotion/yahoo/1.gif");
        this.smiles.put(":(", "/emotion/yahoo/2.gif");
        this.smiles.put(";)", "/emotion/yahoo/3.gif");
        this.smiles.put(":D", "/emotion/yahoo/4.gif");
        this.smiles.put(";;)", "/emotion/yahoo/5.gif");
        this.smiles.put(">:D<", "/emotion/yahoo/6.gif");
        this.smiles.put(":-/", "/emotion/yahoo/7.gif");
        this.smiles.put(":x", "/emotion/yahoo/8.gif");
        this.smiles.put(":\">", "/emotion/yahoo/9.gif");
        this.smiles.put(":P", "/emotion/yahoo/10.gif");
        this.smiles.put(":-*", "/emotion/yahoo/11.gif");
        this.smiles.put("=((", "/emotion/yahoo/12.gif");
        this.smiles.put(":-O", "/emotion/yahoo/13.gif");
        this.smiles.put("X(", "/emotion/yahoo/14.gif");
        this.smiles.put(":>", "/emotion/yahoo/15.gif");
        this.smiles.put("B-)", "/emotion/yahoo/16.gif");
        this.smiles.put(":-S", "/emotion/yahoo/17.gif");
        this.smiles.put("#:-S", "/emotion/yahoo/18.gif");
        this.smiles.put(">:)", "/emotion/yahoo/19.gif");
        this.smiles.put(":((", "/emotion/yahoo/20.gif");
        this.smiles.put(":))", "/emotion/yahoo/21.gif");
        this.smiles.put(":|", "/emotion/yahoo/22.gif");
        this.smiles.put("/:)", "/emotion/yahoo/23.gif");
        this.smiles.put("=))", "/emotion/yahoo/24.gif");
        this.smiles.put("O:)", "/emotion/yahoo/25.gif");
        this.smiles.put(":-B", "/emotion/yahoo/26.gif");
        this.smiles.put("=;", "/emotion/yahoo/27.gif");
        this.smiles.put(":-c", "/emotion/yahoo/101.gif");
        this.smiles.put(":)]", "/emotion/yahoo/100.gif");
        this.smiles.put("~X(", "/emotion/yahoo/102.gif");
        this.smiles.put(":-h", "/emotion/yahoo/103.gif");
        this.smiles.put(":-t", "/emotion/yahoo/104.gif");
        this.smiles.put("8->", "/emotion/yahoo/105.gif");
        this.smiles.put("I-)", "/emotion/yahoo/28.gif");
        this.smiles.put("8-|", "/emotion/yahoo/29.gif");
        this.smiles.put("L-)", "/emotion/yahoo/30.gif");
        this.smiles.put(":-&", "/emotion/yahoo/31.gif");
        this.smiles.put(":-$", "/emotion/yahoo/32.gif");
        this.smiles.put("[-(", "/emotion/yahoo/33.gif");
        this.smiles.put(":O)", "/emotion/yahoo/34.gif");
        this.smiles.put("8-}", "/emotion/yahoo/35.gif");
        this.smiles.put("<:-P", "/emotion/yahoo/36.gif");
        this.smiles.put("(:|", "/emotion/yahoo/37.gif");
        this.smiles.put("=P~", "/emotion/yahoo/38.gif");
        this.smiles.put(":-?", "/emotion/yahoo/39.gif");
        this.smiles.put("#-o", "/emotion/yahoo/40.gif");
        this.smiles.put("=D>", "/emotion/yahoo/41.gif");
        this.smiles.put(":-SS", "/emotion/yahoo/42.gif");
        this.smiles.put("@-)", "/emotion/yahoo/43.gif");
        this.smiles.put(":^o", "/emotion/yahoo/44.gif");
        this.smiles.put(":-w", "/emotion/yahoo/45.gif");
        this.smiles.put(":-<", "/emotion/yahoo/46.gif");
        this.smiles.put(">:P", "/emotion/yahoo/47.gif");
        this.smiles.put("<):)", "/emotion/yahoo/48.gif");
        this.smiles.put("X_X", "/emotion/yahoo/109.gif");
        this.smiles.put(":!!", "/emotion/yahoo/110.gif");
        this.smiles.put("\\m/", "/emotion/yahoo/111.gif");
        this.smiles.put(":-q", "/emotion/yahoo/112.gif");
        this.smiles.put(":-bd", "/emotion/yahoo/113.gif");
        this.smiles.put("^#(^", "/emotion/yahoo/114.gif");
        this.smiles.put(":ar!", "/emotion/yahoo/pirate_2.gif");
    }
}
